home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
asm
/
games
/
readkeys
/
advanced_readkey.s
Wrap
Text File
|
1980-01-03
|
5KB
|
192 lines
*******************************************************************************
* Amiga MC680x0 Hardware "Read-Keyboard" Interrupt Handler
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* This source provides a nice and easy way of polling the Amiga keyboard from
* a hardware environment. The OS *must* be disabled in order to use this code!
* Use this for games, demo`s and the like.
*
* The nice thing about the routine is that it supports Keyboard Qualifiers, not
* many hardware keyboard handlers I have seen in the past do this! Also this
* routine uses cpu-independant & fully relocatable (completly pc-relative) code
*
* Once the Level 2 interrupt has been installed simply call 'ReadKeys' from
* either your level 3 interrupt or your Vblank...
*
* $Outputs: d0.b = current key
* d1.b = keyboard qualifiers (see bit settings below)
*
* In this example if you press "CURSORLEFT" it will flash screen RED.. if
* you continue to hold the key and then hold SHIFT as well it will flash both
* RED and yellow.. a quick example of determining keyboard qualifiers!
*******************************************************************************
LSHIFT = 1 * Bit: 0 (2^0)
RSHIFT = 2 * Bit: 1 (2^1)
CAPS = 4 * Bit: 2 (2^2)
CTRL = 8 * Bit: 3 (2^3)
LALT = 16 * Bit: 4 (2^4)
RALT = 32 * Bit: 5 (2^5)
LAMIGA = 64 * Bit: 6 (2^6)
RAMIGA = 128 * Bit: 7 (2^7)
CURSORUP = $4C * for a complete list of the
CURSORLEFT = $4F * keys.. see RAWKEY codes..
* in Hardware Ref.Manual or
* work them out for yourself!
test: move.l 4.w,a6
jsr -132(a6) * forbid() - disable multitasking
lea Level2(pc),a1 * our new interrupt
move.l _VBR(pc),a4 * get vectorbase
lea OldLev2(pc),a0 * our level2 save
move.l $68(a4),(a0) * save os level2
move.l a1,$68(a4) * install new keyboard level2
*-------------- main loop
main cmp.b #255,$dff006 * wait vblank
bne.s main
DoKeys bsr ReadKeys * Returns: d0.b = key code
* : d1.b = qualifiers
cmp.b #CURSORLEFT,d0
bne.s no_more
cmp.b #LSHIFT,d1
bne.s no_shift
move.w #$ff0,$dff180 * screen yellow..
no_shift move.w #$f00,$dff180 * screen red..
no_more cmp.b #CURSORUP,d0
bne.s no_less
move.w #$00f,$dff180 * screen blue...
no_less
btst #6,$BFE001.l * check leftmouse
bne.s main * if pressed... exit..
*-------------- exit
move.l _VBR(pc),a4 * get vectorbase
move.l OldLev2(pc),$68(a4) * restore os level2
move.l 4.w,a6
jsr -138(a6) * permit() - restore multitask
lea kb_temp(pc),a1
moveq #0,d0
move.b kb.Qualifiers(a1),d0
move.b kb.key(a1),d1
rts
_VBR: dc.l 0 * current vectorbase
OldLev2 dc.l 0
rsreset
kb.qualifiers: rs.b 1
kb.keytmp: rs.b 1
kb.lastkeytmp: rs.b 1
kb.keydelaytmp: rs.b 1
kb.repspeedtmp: rs.b 1
kb.key: rs.b 1
kb.reserved: rs.w 1
kb.sizeof rs.b 0
rsreset
Level2 movem.l d0-d7/a0-a6,-(sp) * preserve irq reg`s..
lea $DFF000.l,a6 * hardware base..
move.w $1E(a6),d0 * intreqr
and.w #8,d0 * level 2 request ?
beq.s Exit_Lev2
btst #3,$BFED01.l * from keyboard?
beq.s _Exit_Lev2
lea kb_temp(pc),a1
move.b $BFEC01,d0 * get key
bset #6,$BFEE01 * start ciaa
not.w d0
ror.b #1,d0
bsr.s GetKeycodes
lea $dff006,a1
moveq #4-1,d2
key6: move.b (a1),d3
key1: cmp.b (a1),d3 * wait 4 rasters... before ciaa
beq.b key1 * stop.. ack`ing keyboard
dbf d2,key6
bclr #6,$BFEE01.l * stop ciaa - acknowlege kb
_Exit_Lev2 move.w #8,$9C(a6) * clear irq bit..
Exit_Lev2 movem.l (sp)+,d0-d7/a0-a6 * restore irq reg`s..
nop * NB: these nop`s are here for 040/060
nop * cache compatibility! you should do
rte * the same for any other hardware irq`s
nop * like a Level3 that you setup to make
nop * sure your code works on MC680x0!
GetKeycodes lea Qualifier_Table(pc),a0
moveq #7,d7
moveq #0,d2
move.b (a1),d3 ;kb.Qualifiers(a1),d3
check_qual1 move.b (a0)+,d1
cmp.b d0,d1
bne.s checkqual2
bset d2,d3
move.b d3,(a1) ;kb.Qualifiers(a1)
rts
checkqual2 add.w #$80,d1
cmp.b d0,d1
bne.s checkqual4
bclr d2,d3
checkqual3 move.b d3,(a1) ;kb.Qualifiers(a1)
rts
checkqual4 addq.b #1,d2
dbra d7,check_qual1
tst.b d0
bpl.s KeyOk
move.b d0,d1
sub.b #$80,d1
cmp.b kb.KeyTMP(a1),d1
beq.s KeyOk
rts
KeyOk move.b d0,kb.KeyTMP(a1)
rts
cnop 0,4
ReadKeys lea kb_temp(pc),a1
moveq #0,d0
move.b kb.KeyTMP(a1),d0
cmp.b kb.LastKeyTMP(a1),d0
beq.s Repeat
move.b d0,kb.LastKeyTMP(a1)
sf.b kb.KeyDelayTMP(a1)
bra.s DoKey3
Repeat tst.b kb.KeyDelayTMP(a1)
beq.s DoKey
subq.b #1,kb.KeyDelayTMP(a1)
bra.s No_Key
DoKey tst.b kb.RepSpeedTMP(a1)
beq.s DoKey2
subq.b #1,kb.RepSpeedTMP(a1)
bra.s No_Key
DoKey2 sf.b kb.RepSpeedTMP(a1)
DoKey3 tst.b d0
bpl.s DoKey4
No_Key st.b d0
DoKey4 move.b d0,kb.KEY(a1) * d0.b = keycode..
move.b (a1),d1 ;kb.Qualifiers(a1),d1 * d1.b = qualifiers..
rts
kb_temp: ds.b kb.sizeof
Qualifier_Table dc.b "`abcdefg"